package benchmark;

import java.io.BufferedOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;

import javax.xml.bind.JAXBException;

import serializer.ISerializer;
import serializer.*;
import config.Config;
import crono.Cronometro;
import domain.SensorData;

public class ThroughputBenchmarkSender {
	public static void main(String[] args) throws IOException, JAXBException {
		Cronometro timer = new Cronometro();
		timer.start();

		boolean done = false;

		ISerializer serializer = new JsonSerializer();

		// do serialization in advance
		byte[][] bufPool = new byte[Config.OBJ_COUNT][];
		for (int i = 0; i < Config.OBJ_COUNT; i++) {
			byte[] buf = serializer.encode(SensorData.get());
			bufPool[i] = buf;
		}

		System.out
				.printf("Benchmark sender. Attemping to connect to host %s on port %d.\n",
						Config.NET_SERVER_IP, Config.NET_SERVER_PORT);

		try (Socket clientSocket = new Socket(Config.NET_SERVER_IP,
				Config.NET_SERVER_PORT,
				InetAddress.getByName(Config.NET_CLIENT_IP),
				Config.NET_CLIENT_PORT);
				OutputStream socketOut = clientSocket.getOutputStream();
				InputStream socketIn = clientSocket.getInputStream();
				DataOutputStream bufferedSocketOut = new DataOutputStream(
						new BufferedOutputStream(socketOut));) {

			for (int i = 0; i < Config.OBJ_COUNT; i++) {

				bufferedSocketOut.writeInt(bufPool[i].length);
				bufferedSocketOut.write(bufPool[i], 0, bufPool[i].length);
			}

			bufferedSocketOut.flush();

			System.out.println("Data sent. Waiting for ACK.");
			int ack = socketIn.read();
			if (ack == Config.TX_ACK_BYTE) {
				System.out.println("ACK received. TX verified.");
				done = true;
			} else {
				System.out.println("Unknown ACK received. TX NOT verified.");
			}
		} catch (UnknownHostException e) {
			System.err.printf("Don't know about host %s.\n",
					Config.NET_SERVER_IP);
		} catch (IOException e) {
			System.out.println("I/O Exception. Details: " + e);
		}

		if (done) {
			timer.stop();
			timer.printThroughput("XML serialization");
		}
	}
}
